import * as monaco from "monaco-editor-core";
import IRichLanguageConfiguration = monaco.languages.LanguageConfiguration;
import ILanguage = monaco.languages.IMonarchLanguage;

export const richLanguageConfiguration: IRichLanguageConfiguration = {
    // If we want to support code folding, brackets ... ( [], (), {}....), we can override some properties here
    // check the doc
      // the default separators except `@$`
  wordPattern: /(-?\d*\.\d\w*)|([^`~!#%^&*()\-=+[{]}\\\|;:'",.<>\/\?\s]+)/g,
  comments: {
      lineComment: '--',
      blockComment: ['/*', '*/']
  },
  brackets: [ //所有的括号
      ['{', '}'],
      ['[', ']'],
      ['(', ')'],
  ],
  autoClosingPairs: [
      { open: '{', close: '}' },
      { open: '[', close: ']' },
      { open: '(', close: ')' },
      { open: '"', close: '"' },
      { open: '\'', close: '\'' },
  ],
  surroundingPairs: [
      { open: '{', close: '}' },
      { open: '[', close: ']' },
      { open: '(', close: ')' },
      { open: '"', close: '"' },
      { open: '\'', close: '\'' },
      { open: '<', close: '>' },
  ],
  folding: {
      markers: {
          start: new RegExp("^\\s*//\\s*(?:(?:#?region\\b)|(?:<editor-fold\\b))"),
          end: new RegExp("^\\s*//\\s*(?:(?:#?endregion\\b)|(?:</editor-fold>))")
      }
  }
};

export const monarchLanguage = <ILanguage>{
    // Set defaultToken to invalid to see what you do not tokenize yet
    defaultToken: 'invalid',
   // Set defaultToken to invalid to see what you do not tokenize yet
    // defaultToken: 'invalid',
  
    keywords: [
        'else' ,
        'then' , 'let' , 'dom', 'ran' , 'min' , 'max' ,'parameters',
        'parameters','output','property','error','single',
        'MR_spec','iteNumbers','iteNumbers','iteRate','MR','input',
        'follow-input','follow-output','relation',"environments"
      ],
    
      typeKeywords: [
          'string','int','double','boolean','decimal' ,
          'float' , 'duration','dateTime' , 'date' , 'time',
          'gYearMonth','gYear' ,'gMonthDay' ,'gDay', 'gMonth',
          'hexBinary' , 'base64Binary' , 'anyURI' , 'QName',
          'NOTATION','Z','R','N','R+'
      ],
    
      operators: [
          '=','>','<','(-','>=','<=','==','subset'
      ],
    
      // we include these common regular expressions
      symbols:  /[=><!~?:&|+\-*/^%]+/,
    
      // C# style strings
      escapes: /\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,
    
      // The main tokenizer for our languages
      tokenizer: {
        root: [
          // identifiers and keywords
          [/--[-]*[ \w]*/,'comment' ],
          [/[a-z_$][\w$]*/, { cases: { '@typeKeywords': 'type',
                                       '@keywords': 'keyword',
                                       '@default': 'identifier' ,
                                       
                                      } }],
          [/[A-Z][\w$]*/, 'type.identifier' ],  // to show class names nicely
    
          // whitespace
          { include: '@whitespace' },
    
          // delimiters and operators
          [/[{}()[]]/, '@brackets'],
          [/[<>](?!@symbols)/, '@brackets'],
          [/@symbols/, { cases: { '@operators': 'operator',
                                  '@default'  : '' } } ],
    
          // @ annotations.
          // As an example, we emit a debugging log message on these tokens.
          // Note: message are supressed during the first load -- change some lines to see them.
          [/@\s*[a-zA-Z_$][\w$]*/, { token: 'annotation', log: 'annotation token: $0' }],
    
          // numbers
          [/\d*\.\d+([eE][-+]?\d+)?/, 'number.float'],
          [/0[xX][0-9a-fA-F]+/, 'number.hex'],
          [/\d+/, 'number'],
    
          // delimiter: after number because of .\d floats
          [/[;,.]/, 'delimiter'],
    
          // strings
          [/"([^"\\]|\\.)*$/, 'string.invalid' ],  // non-teminated string
          [/"/,  { token: 'string.quote', bracket: '@open', next: '@string' } ],
    
          // characters
          [/'[^\\']'/, 'string'],
          [/(')(@escapes)(')/, ['string','string.escape','string']],
          [/'/, 'string.invalid']
        ],
    
        comment: [
          [/--[-]*\w*/,'comment' ],
          [/[^/*]+/, 'comment' ],
          [/\/\*/,    'comment', '@push' ],    // nested comment
          ["\\*/",    'comment', '@pop'  ],
          [/[/*]/,   'comment' ]
        ],
    
        string: [
          [/[^\\"]+/,  'string'],
          [/@escapes/, 'string.escape'],
          [/\\./,      'string.escape.invalid'],
          [/"/,        { token: 'string.quote', bracket: '@close', next: '@pop' } ]
        ],
    
        whitespace: [
          [/[ \t\r\n]+/, 'white'],
          [/\/\*/,       'comment', '@comment' ],
          [/\/\/.*$/,    'comment'],
        ],
      },
}